package com.itheima.ws;
import com.alibaba.fastjson.JSON;
import com.itheima.config.GetHttpSessionConfig;
import com.itheima.utils.MessageUtils;
import com.itheima.ws.pojo.Message;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpSession;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

@ServerEndpoint(value = "/chat", configurator = GetHttpSessionConfig.class)//声明引入httpsession的配置类
@Component
public class ChatEndpoint {

    //用于保存session，键是用户的标识（用户名），值是session
    private static final Map<String,Session> onLineUsers = new ConcurrentHashMap<>();//线程安全的map集合

    private HttpSession httpSession;

    //建立websocket连接后，被调用
    @OnOpen
    public void onOpen(Session session, EndpointConfig config){
        //1.将session进行保存（键是登录的用户名，保存在了HttpSession中，但是这里不能获得，
        //所以需要一个配置类引入，来获得）
        this.httpSession =  (HttpSession)config.getUserProperties().get(HttpSession.class.getName());
        String user =(String) this.httpSession.getAttribute("user");
        onLineUsers.put(user,session);//用户和对应的session对象
        //2.广播消息，将登录的所有用户推送给所有的用户
        String message = MessageUtils.getMessage(true,null,getFrends());
        broadcastAllUsers(message);

    }
    //获得所有的好友列表，map集合的所有键
    public Set getFrends(){
        Set<String> set = onLineUsers.keySet();
        return set;
    }

    //广播消息方法
    private void broadcastAllUsers(String message){
        //遍历map集合
        Set<Map.Entry<String, Session>> entries = onLineUsers.entrySet();
        for (Map.Entry<String, Session> entry : entries) {
            //获取所有用户对应的session对象
            Session session = entry.getValue();
            //发送消息
            try {
                session.getBasicRemote().sendText(message);//发送同步消息，有异常要抛出
            } catch (IOException e) {
                //记录日志
            }
        }
    }
    //浏览器发送消息到服务端，该方法会被调用
    @OnMessage
    public void onMessage(String message){
        //将消息推送给指定用户
       Message msg = JSON.parseObject(message, Message.class);
       //获取消息接收方的用户名
        String toName = msg.getToName();
        String mess = msg.getMessage();
        //获取消息接收方对象的session对象
        Session session = onLineUsers.get(toName);
        String user =(String) this.httpSession.getAttribute("user");
        String msg1 = MessageUtils.getMessage(false, user, mess);
        try {
            session.getBasicRemote().sendText(msg1);
        } catch (IOException e) {
            //记录日志
        }
    }

    //断开websocket连接时被调用，
    @OnClose
    public void onClose(Session session){
        //1.从onLineUsers中删除当前用户的session对象
        String user =(String) this.httpSession.getAttribute("user");
        onLineUsers.remove(user);
        //2.通知其他所有的用户，当前用户下线了
        String message = MessageUtils.getMessage(true,null,getFrends());
        broadcastAllUsers(message);

    }
}
